#include "wqScene.h"
#include "wqMoveItem.h"
#include "wqBtnItem.h"
#include "wqLinkItem.h"
#include <QGraphicsView>

wqScene::wqScene(int idx, QObject* parent)
    : QGraphicsScene(parent)
    , mLastPoint(0,0)
    , mNowPoint(0,0)
    , mLastItem(NULL)
	, mLastBtnItem(NULL)
{
    mbLinking = false;
	mIndex = idx;
    //setBackgroundBrush(QColor(23,45,67));
    setSceneRect(QRectF(QPointF(0,0), QSize(1024, 768)));

    CreateItems();
}

void wqScene::CreateItems()
{
    wqMoveItem* moveItem1 = new wqMoveItem("item1");
    addItem(moveItem1);
    moveItem1->setPos(100,200);

    wqMoveItem* moveItem2 = new wqMoveItem("item2");
    addItem(moveItem2);
    moveItem2->setPos(500,300);

	wqMoveItem* moveItem3 = new wqMoveItem("item3");
	addItem(moveItem3);
	moveItem3->setPos(500,350);


    QObject::connect(moveItem1, SIGNAL(sig_posChanged()), this, SLOT(slot_posChanged()));
    QObject::connect(moveItem2, SIGNAL(sig_posChanged()), this, SLOT(slot_posChanged()));
	QObject::connect(moveItem3, SIGNAL(sig_posChanged()), this, SLOT(slot_posChanged()));
}

void wqScene::mousePressEvent ( QGraphicsSceneMouseEvent * ev )
{
    QGraphicsItem* item = itemAt(ev->scenePos(), QTransform::fromScale(0,0));
	wqBtnItem* lItem = dynamic_cast<wqBtnItem*>(item);
	if(lItem)
	{
		mLastItem = item;

		mLastPoint = ev->scenePos();
	}
	else
	{
		mLastItem = NULL;
	}

	QRectF rect1(sceneRect().center()-QPointF(200,200), QSizeF(100,100));
	if(rect1.contains(ev->scenePos()))
	{
		emit sig_changeScene(1);
	}

	QRectF rect2(sceneRect().center()+QPointF(200,200), QSizeF(100,100));
	if(rect2.contains(ev->scenePos()))
	{
		emit sig_changeScene(2);
	}

    QGraphicsScene::mousePressEvent(ev);
}

void wqScene::mouseMoveEvent( QGraphicsSceneMouseEvent * ev )
{  
    if(mLastItem)
    {
        if(!mLastItem->data(1).toBool())
        {
            mbLinking = true;
        }

        mNowPoint = ev->scenePos();
        mLine.setPoints(mLastPoint, mNowPoint);
        update();

        QGraphicsItem* item = itemAt(ev->scenePos(), QTransform::fromScale(0,0));
		wqBtnItem* lItem = dynamic_cast<wqBtnItem*>(item);
		if(lItem)
		{
			if(mLastBtnItem != lItem)
			{
				if(mLastBtnItem)
				{
					mLastBtnItem->setHoverFlag(false);
				}

				mLastBtnItem = lItem;
			}

			lItem->setHoverFlag(true);
		}
		else
		{
			if(mLastBtnItem)
			{
				mLastBtnItem->setHoverFlag(false);
				mLastBtnItem = NULL;
			}
		}

    }

    QGraphicsScene::mouseMoveEvent(ev);
}

void wqScene::mouseReleaseEvent ( QGraphicsSceneMouseEvent * ev )
{
    if(mLastItem)
    {
        QGraphicsItem* nowItem = itemAt(ev->scenePos(),GetViewTransform());
		if(!nowItem)
		{
			mbLinking = false;
			mLastItem = NULL;

			update();
			QGraphicsScene::mouseReleaseEvent(ev);
			return;
		}

		if(mLastItem == nowItem)
		{
			mbLinking = false;
			mLastItem = NULL;

			update();
			QGraphicsScene::mouseReleaseEvent(ev);
			return;
		}

		wqMoveItem* mItem = dynamic_cast<wqMoveItem*>(nowItem);
		if(mItem)
		{
			mbLinking = false;
			mLastItem = NULL;

			update();
			QGraphicsScene::mouseReleaseEvent(ev);
			return;
		}

		wqLinkItem* lItem = dynamic_cast<wqLinkItem*>(nowItem);
		if(lItem)
		{
			Q_ASSERT(false);
		}

		LInfo lf;
		lf.sname = mLastItem->data(0).toString();
		lf.dname = nowItem->data(0).toString();
		lf.spos = mLastPoint;
		lf.dpos = ev->scenePos();

		wqLinkItem* lineItem = new wqLinkItem(lf);
		addItem(lineItem);

		QString sname = mLastItem->data(0).toString();
		QString dname = nowItem->data(0).toString();

		mMapItems.insert(sname, lineItem);
		mMapItems.insert(dname, lineItem);

		mbLinking = false;
		mLastItem = NULL;

		update();
	}

    QGraphicsScene::mouseReleaseEvent(ev);
}

void wqScene::drawBackground(QPainter *painter, const QRectF &rect)
{
	painter->save();

	painter->setBrush(QColor(23,45,67));
    painter->drawRect(rect);

	// Scene 1
	if(mIndex == 1)
	{
		painter->setBrush(QColor(Qt::green));
	}
	else
	{
		painter->setBrush(QColor(90,34,67));
	}

	{
		painter->drawRect(QRectF(sceneRect().center()-QPointF(200,200), QSizeF(100,100)));

		QFont f = painter->font();
		f.setPointSize(100);
		painter->setFont(f);
		painter->drawText(sceneRect().center()-QPointF(200,100), "1");
	}

	// Scene 2
	if(mIndex == 2)
	{
		painter->setBrush(QColor(Qt::green));
	}
	else
	{
		painter->setBrush(QColor(90,34,67));
	}

	{
		painter->drawRect(QRectF(sceneRect().center()+QPointF(200,200), QSizeF(100,100)));

		QFont f = painter->font();
		f.setPointSize(100);
		painter->setFont(f);
		painter->drawText(sceneRect().center()+QPointF(200,300), "2");
	}

	painter->restore();
}

void wqScene::drawForeground(QPainter *painter, const QRectF &rect)
{
    if(mbLinking)
    {
        painter->setPen(QPen(Qt::green, 5));
        painter->drawLine(mLine);
    }
}

QTransform wqScene::GetViewTransform()
{
    QList<QGraphicsView*> allViews = views();
    if(!allViews.isEmpty())
    {
        return allViews.first()->transform();
    }

    return QTransform();
}

void wqScene::slot_posChanged()
{
	QGraphicsItem* item = qobject_cast<QGraphicsItem*>(sender());
	if(item)
	{
		const QString itemName = item->data(0).toString();
		
		QStringList keyList;
		keyList.push_back(itemName+"01");
		keyList.push_back(itemName+"02");
		keyList.push_back(itemName+"03");

		foreach(QString key, keyList)
		{
			QGraphicsItem* curItem = GetCurrentItem(key);
			QList<wqLinkItem*> lineItems = mMapItems.values(key);
			foreach(wqLinkItem* lineItem, lineItems)
			{
				const LInfo li = lineItem->data(1).value<LInfo>();

				if(key == li.sname)
				{
					QPointF pos(curItem->scenePos()+curItem->boundingRect().center());
					lineItem->AdjustSourcePos(pos);
				}
				else
				{
					QPointF pos(curItem->scenePos()+curItem->boundingRect().center());
					lineItem->AdjustDestPos(pos);
				}
			}
		}
	}
}

QGraphicsItem* wqScene::GetCurrentItem(const QString& name)
{
    QList<QGraphicsItem*> allItems = items();
    foreach(QGraphicsItem* item, allItems)
    {
        QString na = item->data(0).toString();
        if(na == name)
        {
            return item;
        }
    }

    return NULL;
}
